<template>
  <div class="login-page" :style="backgroundStyle">
    <div class="bg-overlay" />
    <div class="login-card animate-in">
      <div class="header">
        <div class="logo">🏝️</div>
        <div class="titles">
          <h2 class="title">{{ $t('login.title') }}</h2>
          <p class="subtitle">{{ $t('login.subtitle') }}</p>
        </div>
        <el-dropdown class="lang-switch" @command="switchLang">
          <span class="el-dropdown-link">
            {{ locale.toUpperCase() }}
          </span>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item command="zh-CN">中文</el-dropdown-item>
              <el-dropdown-item command="en">English</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>

      <el-form ref="formRef" :model="form" :rules="rules" label-position="top" class="form">
        <el-form-item prop="email">
          <el-input
            v-model="form.email"
            :placeholder="$t('login.emailPlaceholder') as string"
            clearable
            autocomplete="email"
            inputmode="email"
          >
            <template #prefix>
              <el-icon class="input-icon"><Message /></el-icon>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item prop="password">
          <el-input
            v-model="form.password"
            type="password"
            :placeholder="$t('login.passwordPlaceholder') as string"
            show-password
            autocomplete="current-password"
          >
            <template #prefix>
              <el-icon class="input-icon"><Lock /></el-icon>
            </template>
          </el-input>
        </el-form-item>

        <el-button
          type="primary"
          class="submit-btn gradient"
          @click="onSubmit"
          :loading="loading"
          >{{ $t('login.signIn') }}</el-button
        >
      </el-form>
    </div>

    <div class="fab-group">
      <el-tooltip :content="$t('login.bgSetting') as string" placement="left">
        <el-button circle type="primary" @click="openBgDialog">
          <el-icon><Picture /></el-icon>
        </el-button>
      </el-tooltip>
    </div>

    <el-dialog v-model="bgDialogVisible" :title="$t('login.dialogTitle')" width="520px">
      <el-tabs v-model="bgTab">
        <el-tab-pane :label="$t('login.tabUrl')" name="url">
          <el-input v-model="bgUrl" :placeholder="$t('login.urlPlaceholder') as string" />
        </el-tab-pane>
        <el-tab-pane :label="$t('login.tabUpload')" name="upload">
          <el-upload
            class="upload"
            :auto-upload="false"
            :show-file-list="false"
            :on-change="onFileChange"
            accept="image/*"
          >
            <el-button type="primary">{{ $t('login.tabUpload') }}</el-button>
            <span class="upload-tip" v-if="uploadFileName">{{
              $t('login.selected', { name: uploadFileName })
            }}</span>
          </el-upload>
        </el-tab-pane>
        <el-tab-pane :label="$t('login.tabPreview')" name="preview">
          <div class="preview">
            <img v-if="bgUrl" :src="bgUrl" alt="preview" />
            <span v-else class="preview-tip">{{ $t('login.previewTip') }}</span>
          </div>
        </el-tab-pane>
      </el-tabs>

      <el-divider>{{ $t('login.fit') }}</el-divider>
      <el-radio-group v-model="bgFit" class="fit-group">
        <el-radio-button label="cover">{{ $t('login.fitCover') }}</el-radio-button>
        <el-radio-button label="contain">{{ $t('login.fitContain') }}</el-radio-button>
        <el-radio-button label="fill">{{ $t('login.fitFill') }}</el-radio-button>
      </el-radio-group>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="resetBackground">{{ $t('login.resetDefault') }}</el-button>
          <el-button type="primary" @click="applyBackground">{{ $t('login.apply') }}</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { Picture, Message, Lock } from '@element-plus/icons-vue'
import type { UploadFile, FormInstance, FormRules } from 'element-plus'
import { loginAPI } from '@/api/login'
import type { LoginParams } from '@/type/login'
const { t, locale } = useI18n()
import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores'
import { useMenuIdStore } from '@/stores'
const menuIdStore = useMenuIdStore()
const userStore = useUserStore()
const router = useRouter()
const DEFAULT_BG = 'https://lvyou-1332935562.cos.ap-nanjing.myqcloud.com/lvyou/IMG_0571.PNG'

const formRef = ref<FormInstance>()
const form = ref<LoginParams>({ email: '', password: '' })
const loading = ref(false)

const rules = ref<FormRules>({
  email: [
    { required: true, message: t('login.emailRequired'), trigger: 'blur' },
    { type: 'email', message: t('login.emailInvalid'), trigger: ['blur', 'change'] },
  ],
  password: [
    { required: true, message: t('login.passwordRequired'), trigger: 'blur' },
    { min: 6, message: t('login.passwordMin'), trigger: 'blur' },
  ],
})

const bgDialogVisible = ref(false)
const bgTab = ref<'url' | 'upload' | 'preview'>('url')
const bgUrl = ref('')
const uploadFileName = ref('')
const backgroundDataUrl = ref<string | null>(null)

const STORAGE_KEY = 'login_background_image'
const STORAGE_FIT_KEY = 'login_background_fit'

const bgFit = ref<'cover' | 'contain' | 'fill'>(
  (localStorage.getItem(STORAGE_FIT_KEY) as 'cover' | 'contain' | 'fill') || 'cover',
)

const resolvedBgUrl = computed(() => toHiDpiUrl(backgroundDataUrl.value || DEFAULT_BG))

const backgroundStyle = computed(() => ({
  backgroundImage: `url(${resolvedBgUrl.value})`,
  backgroundSize: bgFit.value === 'fill' ? '100% 100%' : bgFit.value,
}))

watch(bgFit, (val) => localStorage.setItem(STORAGE_FIT_KEY, val))

function switchLang(code: 'zh-CN' | 'en') {
  locale.value = code
  localStorage.setItem('app_locale', code)
}

function openBgDialog() {
  bgDialogVisible.value = true
}

function onFileChange(file: UploadFile) {
  uploadFileName.value = file.name
  if (file.raw) {
    const reader = new FileReader()
    reader.onload = () => {
      bgUrl.value = String(reader.result || '')
      bgTab.value = 'preview'
    }
    reader.readAsDataURL(file.raw)
  } else {
    ElMessage.warning(t('login.notReadFile'))
  }
}

function applyBackground() {
  if (!bgUrl.value) {
    ElMessage.warning(t('login.pleaseInput'))
    return
  }
  backgroundDataUrl.value = bgUrl.value
  localStorage.setItem(STORAGE_KEY, bgUrl.value)
  bgDialogVisible.value = false
  ElMessage.success(t('login.updated'))
}

function resetBackground() {
  localStorage.removeItem(STORAGE_KEY)
  backgroundDataUrl.value = DEFAULT_BG
  bgUrl.value = ''
  uploadFileName.value = ''
  ElMessage.success(t('login.restored'))
}

onMounted(() => {
  const saved = localStorage.getItem(STORAGE_KEY)
  backgroundDataUrl.value = saved || DEFAULT_BG
})

function toHiDpiUrl(rawUrl: string): string {
  if (rawUrl.startsWith('data:') || rawUrl.startsWith('blob:')) return rawUrl
  const deviceDpr = Math.min(window.devicePixelRatio || 1, 3)
  const targetWidth = Math.ceil(window.screen.width * deviceDpr)
  try {
    if (rawUrl.includes('images.unsplash.com')) {
      const u = new URL(rawUrl, window.location.origin)
      u.searchParams.set('auto', 'format')
      u.searchParams.set('fit', 'crop')
      u.searchParams.set('w', String(Math.max(targetWidth, 1920)))
      u.searchParams.set('q', '90')
      u.searchParams.set('dpr', String(deviceDpr))
      return u.toString()
    }
    if (rawUrl.includes('myqcloud.com')) {
      if (rawUrl.includes('?imageMogr2')) return rawUrl
      const sep = rawUrl.includes('?') ? '&' : '?'
      return `${rawUrl}${sep}imageMogr2/thumbnail/${Math.max(targetWidth, 1920)}x/quality/90/format/webp`
    }
    return rawUrl
  } catch {
    return rawUrl
  }
}

async function onSubmit() {
  if (!formRef.value) return
  await formRef.value.validate(async (valid) => {
    if (!valid) return
    loading.value = true
    try {
      const res = await loginAPI(form.value)
      if (res.msg !== 'SUCCESS') {
        ElMessage.error(res.msg || t('login.loginFailed'))
        return
      }
      userStore.setUserInfo(res.data)
      menuIdStore.setMenuId('1')
      ElMessage.success(t('login.loginSuccess'))
      router.push('/index')
    } finally {
      loading.value = false
    }
  })
}
</script>

<style scoped>
:root {
  --brand-primary: #42b883;
  --brand-primary-2: #4caf50;
}

.login-page {
  position: relative;
  width: 100vw;
  height: 100vh;
  background-position: center;
  background-repeat: no-repeat;
  display: grid;
  place-items: center;
  overflow: hidden;
  image-rendering: auto;
}

.bg-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.15) 0%, rgba(0, 0, 0, 0.35) 100%);
  pointer-events: none;
}

.login-card {
  position: relative;
  width: min(92vw, 560px);
  background: rgba(255, 255, 255, 0.75);
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 18px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.22);
  padding: 28px 34px 30px;
  backdrop-filter: blur(14px) saturate(140%);
}

.header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}

.lang-switch {
  margin-left: auto;
  font-size: 12px;
  color: #6b7280;
  cursor: pointer;
}

.logo {
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-2));
  color: #fff;
  font-size: 22px;
}

.titles {
  display: flex;
  flex-direction: column;
}

.title {
  margin: 0;
  font-size: 24px;
  font-weight: 800;
  background: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-2));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.subtitle {
  margin: 4px 0 12px;
  color: #6b7280;
  font-size: 13px;
}

.form :deep(.el-form-item) {
  margin-bottom: 16px;
}

.input-icon {
  color: #9ca3af;
}

.submit-btn {
  width: 100%;
  height: 42px;
  font-size: 15px;
  letter-spacing: 1px;
}

.gradient {
  background-image: linear-gradient(135deg, var(--brand-primary), var(--brand-primary-2));
  border: none;
}

.gradient:hover {
  filter: brightness(1.05);
}

.fab-group {
  position: fixed;
  right: 18px;
  bottom: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.fit-group {
  display: flex;
  gap: 8px;
}

.upload {
  display: inline-flex;
  align-items: center;
  gap: 12px;
}

.upload-tip {
  color: #888;
}

.preview {
  display: grid;
  place-items: center;
  height: 240px;
  background: #f5f7fa;
  border-radius: 8px;
  overflow: hidden;
}

.preview img {
  max-width: 100%;
  max-height: 100%;
  object-fit: cover;
}

.preview-tip {
  color: #999;
  font-size: 13px;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translate3d(0, 14px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

.animate-in {
  animation: fadeInUp 520ms ease-out both;
}

/* Mobile <= 576px */
@media (max-width: 576px) {
  .login-card {
    width: 94vw;
    padding: 18px 16px 20px;
    border-radius: 14px;
  }
  .header {
    gap: 10px;
    margin-bottom: 8px;
  }
  .logo {
    width: 40px;
    height: 40px;
    font-size: 20px;
    border-radius: 10px;
  }
  .title {
    font-size: 20px;
  }
  .subtitle {
    font-size: 12px;
    margin: 2px 0 8px;
  }
  .lang-switch {
    font-size: 11px;
  }
  .form :deep(.el-form-item) {
    margin-bottom: 12px;
  }
  .submit-btn {
    height: 40px;
    font-size: 14px;
  }
  /* 弹窗在小屏的宽度/间距优化 */
  :deep(.el-dialog) {
    width: 92vw !important;
    margin: 8vh auto 0 !important;
  }
  :deep(.el-dialog__body) {
    padding: 14px 16px !important;
  }
  :deep(.el-dialog__header) {
    padding: 12px 16px 0 !important;
  }
  .preview {
    height: 200px;
  }
}
</style>
